from socket import *
import _thread as thread
import time
import sys
import random
                    
print('Start server')
server=socket(AF_INET,SOCK_STREAM)
server.bind(('',50000))
server.listen(500)
client_online=[]
battle=[]
def handleClient(connect,status=True):
      id_process=thread.get_ident()
      global request
      global client_online
      try:
            while status==True:
                  login=connect.recv(1024)
                  login=login.decode()
                  print(login, ' is conected')
                  connect.send(b'Autorisated is ok')
                  client_online.append(login)
                  while True:
                        game_request=connect.recv(1024)
                        game_request=game_request.decode()
                        print(login, game_request)
                        if game_request=='disc':
                              status=False
                              break
                        if game_request=='online':
                              i=''
                              for k in client_online:
                                    i+=k+','
                              i=i[:-1]
                              print('Online is ',i)
                              connect.send(i.encode())
                        if game_request=='battle vs comp':
                              connect.send(b'okPvE')
                              battleroom_pve(connect,login)
                        if game_request=='battle vs player':
                              print(login,' Ready for battle\n')
                              connect.send(b'okPvP')
                              battle.append((connect,login))
                              if len(battle)== 2:
                                    battleroom_pvp(battle[0],battle[1])
                         
      except:
            print(sys.exc_info())
      connect.close()
      client_online.remove(login)
      
      
def dispatcher():
      global battle
      while True:
            connect,adress=server.accept()
            print('Server connected by',adress)
            thread.start_new_thread(handleClient,(connect,))

def battleroom_pvp(user1,user2):
      print('The users in the room')
      
      def now():
            return time.ctime()
      a=[user1,user2]
      while len(a)==2:
            player1=Player(user1[0],user1[1])
            player2=Player(user2[0],user2[1])
            main=Game(player1,player2)
            main.start()
def battleroom_pve(conn,user):
      print('The user in the room')
      player1=Player(conn,user)
      computer=Computer()
      main=Game(player1,computer)
      main.start()
      print("Game Over")

class Player():
      head='head'
      chest='chest'
      legss='legs'
      
      def damage():
            return random.randint(12,30)
      def armor():
            return random.randint(0,40)
      
      def __init__(self,conn,login,hp=100):
            self.conn=conn
            self.name=login
            self.hp=hp
            
      def self_damage(self,value):
            self.hp=self.hp-value
            
      def attack(self):
            text='at'
            self.conn.send(text.encode())
            choose_at=self.conn.recv(1024)
            choose_at=choose_at.decode()
            if choose_at=='1':
                  choose_at=Player.head
            if choose_at=='2':
                  choose_at=Player.chest
            if choose_at=='3':
                  choose_at=Player.legss
            return (Player.damage(),choose_at)
      
      def defend(self):
            text='def'
            text=text.encode()
            self.conn.send(text)
            choose_def=self.conn.recv(1024)
            choose_def=choose_def.decode()
            if choose_def=='1':
                  choose_def=Player.head
            if choose_def=='2':
                  choose_def=Player.chest
            if choose_def=='3':
                  choose_def=Player.legss
            return (Player.armor(),choose_def)
      
class Computer(Player):
      def __init__(self,conn=None,login='Computer'):
            Player.__init__(self,conn,login,hp=100)
            self.name=login
      def attack(self,):
            return (Player.damage(),(random.choice((Player.head,Player.chest,Player.legss))))
      def defend(self):
            return (Player.armor(),(random.choice((Player.head,Player.chest,Player.legss))))


class Game():
      def __init__(self,player1,player2):
            self.player1=player1
            self.player2=player2
            self.handller_player=[player1,player2]
            for i in self.handller_player:
                  if i.name=='Computer':
                        self.handller_player.remove(i)
      def clien_send_handler(self,text):
            for i in self.handller_player:
                  i.conn.send(text.encode())
                  time.sleep(0.2)
                  
      def start(self):
            step1=random.randint(0,1)
            if step1==0:
                  self.first=self.player1
                  self.second=self.player2
            if step1==1:
                  self.first=self.player2
                  self.second=self.player1
            self.handler_player=[self.first,self.second]
            self.clien_send_handler('Start')
            self.clien_send_handler('First attacking will %s' % self.first.name)
            winner=None
            count_of_rounds=0
            self.clien_send_handler('Starting battle')
            while self.first.hp >0 and self.second.hp >0:
                  """
                  Первый удар
                  """
                  self.clien_send_handler('-----------------------------------\n')
                  count_of_rounds+=1
                  self.clien_send_handler('Start round %s\n' % count_of_rounds)
                  print('request attack')
                  damage,choose_first=self.first.attack()
                  print(damage,choose_first,self.first.name)
                  print('request defend')
                  defend,choose_second=self.second.defend()
                  print(defend,choose_second)
                  if choose_first==choose_second:
                        if defend>=damage:
                              defend=damage
                        self.second.hp-=(damage-defend)
                  if choose_first!=choose_second:
                        defend=0
                        if damage>self.second.hp:
                              self.clien_send_handler('>>>%s attacking %s in %s on %s dmg. %s use block on %s, block is %s' %(self.first.name,
                                                                                                        self.second.name,
                                                                                                        choose_first,
                                                                                                        damage,
                                                                                                        self.second.name,
                                                                                                        choose_second,
                                                                                                        defend))
                              self.second.hp=0
                              winner=self.first.name
                              break
                        self.second.hp-=damage
                  self.clien_send_handler('>>>%s attacking %s in %s on %s dmg. %s use block on %s, block is %s' %(self.first.name,
                                                                                          self.second.name,
                                                                                          choose_first,
                                                                                          damage,
                                                                                          self.second.name,
                                                                                          choose_second,
                                                                                          defend))
                  self.clien_send_handler('\n%s have %s hp, %s have %s hp\n' % (self.second.name,self.second.hp,
                                                          self.first.name,self.first.hp))

                  
                  print('request attack')
                  damage,choose_second=self.second.attack()
                  print(damage,choose_first,self.second.name)
                  print('request defend')
                  defend,choose_first=self.first.defend()
                  if choose_second==choose_first:
                        if defend>=damage:
                              defend=damage
                        self.first.hp-=(damage-defend)
                  if choose_second!=choose_first:
                        defend=0
                        if damage>self.first.hp:
                              self.clien_send_handler('>>>%s attacking %s in %s on %s dmg. %s use block on %s, block is %s' %(self.second.name,
                                                                                                        self.first.name,
                                                                                                        choose_second,
                                                                                                        damage,
                                                                                                        self.first.name,
                                                                                                        choose_first,
                                                                                                        defend))
                                                                                                        
                              self.first.hp=0
                              winner=self.second.name
                              break
                        self.first.hp-=damage
                  self.clien_send_handler('>>>%s attacking %s in %s on %s dmg. %s use block on %s, block is %s' %(self.second.name,
                                                                                          self.first.name,
                                                                                          choose_second,
                                                                                          damage,
                                                                                          self.first.name,
                                                                                          choose_first,
                                                                                          defend))
                  self.clien_send_handler('%s have %s hp, %s have %s hp\n' % (self.first.name,self.first.hp,
                                                          self.second.name,self.second.hp))
            self.clien_send_handler('**---****************---****************---************-----******')      
            self.clien_send_handler('%s Have %s hp. %s have %s hp'%(self.first.name,self.first.hp,self.second.name,self.second.hp))
            self.clien_send_handler('!!!The winner in battle is - %s' % winner)
            self.clien_send_handler('Game Over')
            
                        
dispatcher()








            
